`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2020/09/15 20:10:03
// Design Name: 
// Module Name: JumpAddress
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module JumpAddress(
    input   wire [31:0] i_pc,
    input   wire [31:0] i_inst,
    input   wire [31:0] i_rs_out,
    input   wire [31:0] i_rt_out,
    
    output  wire [31:0] o_jump_addr
    );
    
    wire [5:0] op;
    wire [4:0] rt;
    wire [5:0] funct;
    wire [25:0] index;
    wire [15:0] offset;
    assign op = i_inst[31:26];
    assign rt = i_inst[20:16];
    assign funct = i_inst[5:0];
    assign index = i_inst[25:0];
    assign offset = i_inst[15:0];
    
    wire z;
    wire gtz;
    wire ltz;
    wire eq;
    
    assign z = ~(|i_rs_out);
    assign gtz = i_rs_out[31] == 0 && z != 1;
    assign ltz = i_rs_out[31] == 1;
    assign eq = i_rs_out == i_rt_out;
    
    wire [31:0] shift;
//    assign shift
//        = index[15] == 1 ? {14'b11111111111111, index, 2'b00}
//        : {14'b00000000000000, index, 2'b00}
//    ;
    assign shift = {{14{offset[15]}}, offset, 2'b00};
    
    wire [31:0] na;
    assign na = i_pc + 4 + shift;
    
//    wire [31:0] regimm;
//    assign regimm
//        = rt == `RT_BLTZ ? (ltz ? na : 0)
//        : rt == `RT_BLTZAL ? (ltz ? na : 0)
//        : rt == `RT_BGEZ ? (gtz || z ? na : 0)
//        : rt == `RT_BGEZAL ? (gtz || z ? na : 0)
//        : 0
//    ;
    
//    wire [31:0] special;
//    assign special
//        = funct == `FUNCT_JR ? i_rs_out
//        : funct == `FUNCT_JALR ? i_rs_out
//        : 0
//    ;
    
    wire [31:0] temp;
    assign temp = i_pc + 4;
    wire [31:0] na2;
    assign na2 = {temp[31:28], index, 2'b00};
//    assign o_jump_addr
//        = op == `OP_REGIMM ? regimm
//        : op == `OP_SPECIAL ? special
//        : op == `OP_BEQ ? (eq ? na : 0)
//        : op == `OP_BGTZ ? (gtz ? na : 0)
//        : op == `OP_BLEZ ? (ltz || z ? na : 0)
//        : op == `OP_BNE ? (!eq ? na : 0)
//        : op == `OP_J ? 
//        : 0
//    ;
    
    assign o_jump_addr
        = op == `OP_REGIMM ? na
        : op == `OP_SPECIAL ? i_rs_out
        : op == `OP_BEQ ? na
        : op == `OP_BGTZ ? na
        : op == `OP_BLEZ ? na
        : op == `OP_BNE ? na
        : op == `OP_J ? na2
        : op == `OP_JAL ? na2
        : 0
    ;
    
endmodule
